import { logger } from '../logger.js';
import request from '../request.js';
import { pick, isEqual } from 'lodash-es';
import updateReviewService from './updateReviewService.js';
import { AxiosError } from 'axios';

interface Attachment {
  id: string;
  name: string;
  usage: string;
  url: string;
}
interface ReviewComment {
  attachmentList: Attachment[];
}

const queryReviewService = {
  attach: async ({ documentName, document, context }) => {
    // 应该引入 zod 工具，对上下游进行校验，以保证逻辑正常
    if (!documentName.includes('.')) {
      logger.error('documentName is invalid', documentName);
      return;
    }
    const documentNameArr = documentName.split('.');
    if (documentNameArr.length !== 2) {
      logger.error('documentName is invalid', documentName);
      return;
    }
    const reviewInternalKey = documentNameArr[1];
    if (reviewInternalKey) {
      let response;
      try {
        const webhookUrl = process.env.WEBHOOK_URL_GET.replace('{review-internal-key}', reviewInternalKey);
        response = await request.get(webhookUrl, { headers: { Authorization: context.token } });
      } catch (e) {
        if ((e as AxiosError).response) {
          logger.info(`request before error: ${JSON.stringify((e as AxiosError).request?.data)}`);
          logger.error(`response error: ${JSON.stringify((e as AxiosError).response?.data)}`);
        }
        logger.error(`Caught error in extension-webhook: ${e}`);
        return;
      }
      if (!response.data.success) {
        logger.error('获取数据失败', response.data);
        return;
      }

      const res = response.data.data;
      const reviewConfig = document.getMap('reviewConfig');
      const reviewContent = document.getMap('reviewContent');
      const reviewComment = document.getMap('reviewComment');
      const reviewPrepareTime = document.getMap('reviewPrepareTime');
      const noReviewComment = document.getMap('noReviewComment');
      const auditRecord = document.getMap('auditRecord');
      const reviewChangeQueue = document.getArray('reviewChangeQueue');
      const currentReviewStatus = document.getMap('currentReviewStatus');

      // 初始化数据
      document.transact(() => {
        currentReviewStatus.set('data', {
          reviewStatus: res.reviewStatus,
        });

        reviewConfig.set(
          'data',
          pick(res, [
            'reviewType', // 评审类型
            'reviewLocation', // 评审地点
            'authorList', // 作者
            'criticalReviewerList', // 关键评审人
            'reviewerList', // 非关键评审人
            'moderator', // 评审主持人
            'reviewTime', // 评审开始时间
            'planFinishTime', // 评审结束时间
            'reviewDuration', // 实际会议评审时长
            'reviewCreator', // 评审创建者
            'reviewStatus', // 评审状态
            'name', //评审名称
            'processId', // 流程id
            'mgtObjId', // 管理对象id
            'mgtObjType', // 管理对象类型
            'templateName', // 模板名称
            'templateId', // 模板id
            'templateVersion', // 模板版本号
          ]),
        );
        reviewContent.set('data', {
          reviewContentHeaders: res.reviewContentHeaders,
          reviewContentRowValues: res.reviewContentRowValues,
        });

        reviewComment.set('data', {
          reviewCommentList: res.reviewCommentList.map((item: ReviewComment) => {
            let commentPicList = [];
            let resolutionPicList = [];
            item.attachmentList.forEach((item) => {
              const picList = { uid: item.id, name: item.name, status: 'done', url: item.url };
              if (item.usage === 'comment') {
                commentPicList.push(picList);
              } else if (item.usage === 'resolution') {
                resolutionPicList.push(picList);
              }
            });
            return { ...item, commentPicList, resolutionPicList };
          }),
        });
        reviewPrepareTime.set('data', {
          prepareTimeList: res.prepareTimeList,
        });
        noReviewComment.set('data', {
          noCommentsCriticalReviewerList: res.noCommentsCriticalReviewerList,
        });
        auditRecord.set('data', { auditRecordList: res.auditRecordList });
      });

      // 监听评论数据变更后增量同步
      reviewChangeQueue.observe((yarrayEvent) => {
        if (yarrayEvent.currentTarget.length) {
          updateReviewService.save({ document, documentName, reason: 'reviewChangeQueue' }, yarrayEvent.currentTarget);
        }
      });

      reviewConfig.observe((yevent) => {
        logger.info('reviewConfig changed');
        if (isEqual(yevent.currentTarget.toJSON().data, yevent.changes.keys.get('data')?.oldValue)) {
          logger.info('no data changed');
          return;
        }
        updateReviewService.save({ document, documentName, reason: 'reviewConfig' });
      });
      reviewContent.observe((yevent) => {
        logger.info('reviewContent changed');
        if (isEqual(yevent.currentTarget.toJSON().data, yevent.changes.keys.get('data')?.oldValue)) {
          logger.info('no data changed');
          return;
        }
        updateReviewService.save({ document, documentName, reason: 'reviewContent' });
      });
      reviewPrepareTime.observe((yevent) => {
        logger.info('reviewPrepareTime changed');
        if (isEqual(yevent.currentTarget.toJSON().data, yevent.changes.keys.get('data')?.oldValue)) {
          logger.info('no data changed');
          return;
        }
        updateReviewService.save({ document, documentName, reason: 'reviewPrepareTime' });
      });
      noReviewComment.observe((yevent) => {
        logger.info('noReviewComment changed');
        if (isEqual(yevent.currentTarget.toJSON().data, yevent.changes.keys.get('data')?.oldValue)) {
          logger.info('no data changed');
          return;
        }
        updateReviewService.save({ document, documentName, reason: 'noReviewComment' });
      });
    }
    return document;
  },
};

export default queryReviewService;
